package com.tca.common.learning.elasticsearch;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.tca.common.core.utils.ValidateUtils;
import com.tca.common.learning.elasticsearch.bean.User;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zhoua
 * @date 2022/1/11 22:42
 * 文档操作
 */
@Slf4j
public class DocOperator {

    /**
     * 核心客户端
     */
    private static RestHighLevelClient client = EsClientFactory.getClient();

    public static void main(String[] args) throws IOException {

        // 插入文档
//        insertDoc("user", new User("Messi", "男", 34));

        // 增量更新文档
//        Map<String, Object> updateParam =  new HashMap<>(2);
//        updateParam.put("age", 35);
//        updateDoc("user", "1001", updateParam);

        // 查询文档
//        User user = getById("user", "1003", User.class);

        // 删除文档
//        deleteById("user", "1001");

        // 查询文档
//        user = getById("user", "1001", User.class);

        // 批量添加
        HashMap<String, User> map = Maps.newHashMap();
        map.put("1002", new User("Ronaldo", "男", 37));
        map.put("1003", new User("Xavi", "男", 40));
        map.put("1004", new User("Neymar", "男", 30));
        insertBatchDoc("user", map);

        // 批量删除
//        deleteBatchById("user", Lists.newArrayList("1002", "1003", "1004"));

        client.close();

    }

    /**
     * 批量删除
     * @param index
     * @param idList
     * @throws IOException
     */
    private static void deleteBatchById(String index, List<String> idList) throws IOException {
        BulkRequest request = new BulkRequest();
        idList.forEach(id -> {
            request.add(new DeleteRequest()
                    .index(index)
                    .id(id));
        });
        BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
        log.info("批量删除结果: {}", response);
    }

    /**
     * 批量插入
     * @param index
     * @param map
     * @param <T>
     * @throws IOException
     */
    private static <T> void insertBatchDoc(String index, HashMap<String, T> map) throws IOException {
        if (ValidateUtils.isEmpty(map)) {
            return;
        }
        BulkRequest request = new BulkRequest();
        map.entrySet().forEach(entry -> {
            request.add(new IndexRequest()
                    .index(index)
                    .id(entry.getKey())
                    // 这里需要将对象转成json字符串
                    .source(JSONObject.toJSONString(entry.getValue()), XContentType.JSON));
        });
        BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
        log.info("插入结果: {}", response);
    }

    /**
     * 通过id删除
     * @param index
     * @param id
     */
    private static void deleteById(String index, String id) throws IOException {
        DeleteRequest request = new DeleteRequest()
                .index(index)
                .id(id);
        DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
        log.info("删除结果: {}", response.getResult());
    }

    /**
     * 通过id查询
     * @param index
     * @param id
     * @param clazz
     * @param <T>
     * @return T
     */
    private static <T> T getById(String index, String id, Class<T> clazz) throws IOException {
        GetRequest request = new GetRequest()
                .index(index)
                .id(id);
        GetResponse response = client.get(request, RequestOptions.DEFAULT);
        String resultStr = response.getSourceAsString();
        log.info("获取结果: {}", response);
        return ValidateUtils.isEmpty(resultStr)? null: JSONObject.parseObject(resultStr, clazz);
    }

    /**
     * 更新文档
     * @param index
     * @param id
     * @param updateParam
     */
    private static void updateDoc(String index, String id, Map<String, Object> updateParam) throws IOException {
        UpdateRequest request = new UpdateRequest().index(index).id(id);
        updateParam.entrySet().forEach(entry -> request.doc(entry.getKey(), entry.getValue()));
        UpdateResponse response = client.update(request, RequestOptions.DEFAULT);

        log.info("更新结果: {}", response.getResult());
    }

    /**
     * 插入文档
     * @param index
     * @param user
     */
    private static void insertDoc(String index, User user) throws IOException {
        IndexRequest request = new IndexRequest();
        request.index(index)
                .id("1001")
                .source(JSONObject.toJSONString(user), XContentType.JSON);
        IndexResponse response = client.index(request, RequestOptions.DEFAULT);

        log.info("添加结果: {}", response.getResult());
    }

}
